#if !defined(MAP_INFO_H_)
#define MAP_INFO_H_

#include "fixed_array.h"
#include "point_type.h"
namespace autodrive {
namespace perception {
///@brief max map element point number
constexpr std::uint32_t kMaxMapElementPointsNum{512};
/// @brief max map element number
constexpr std::uint32_t KMaxMapElementsNum{128};
/// @brief center line topo id number
constexpr std::uint32_t KCenterlineTopoIDNum{2};
/// @brief max road marking number
constexpr std::uint32_t KMaxRoadMarkingCategoryNum{8};
/// @brief max point reserve feature number
constexpr std::uint32_t KMaxReserveFeatureNum{16};
/// @brief max id length
constexpr std::uint32_t KMaxIDLength{64};

struct MapPointsElement;

using MapElementPoint = Pointxf<float, KMaxReserveFeatureNum>;

using MapElementPointSet =
    fixed_array<MapElementPoint, kMaxMapElementPointsNum>;

using MapElementPointSetConstPtr = MapElementPointSet const *;

template <typename T>
using MapElementSet = fixed_array<T, KMaxMapElementsNum>;

using MapPointsElementConstPtr = MapPointsElement const *;

using MapPointsElementPtr = MapPointsElement *;

/// @brief lane divider line type
enum class LaneDividerLineType : std::int8_t {
  /// @brief none
  UNKNOWN = 0,
  /// @brief solid
  SOLID = 1,
  /// @brief dashed
  DASHED = 2,
};

/// @brief lane divider color
enum class LaneDividerColor : std::int8_t {
  /// @brief none
  UNKNOWN = 0,
  /// @brief white
  WHITE = 1,
  /// @brief yellow
  YELLOW = 2,
  /// @brief blue
  BLUE = 3,
  /// @brief green
  GREEN = 4,
  /// @brief red
  RED = 5,
};

/// @brief road edge category
enum class RoadEdgeCategory : std::int8_t {
  /// @brief none
  UNKNOWN = 0,
  /// @brief road edge
  ROAD_EDGE = 1,
  /// @brief traffic barrier
  TRAFFIC_BARRIER = 2,
};

/// @brief roadmarking category
enum class RoadMarkingCategory : std::int8_t {
  /// @brief unknown
  UNKNOWN = 0,
  /// @brief straight
  STRAIGHT = 1,
  /// @brief left
  LEFT = 2,
  /// @brief right
  RIGHT = 3,
  /// @brief u_turn
  U_TURN = 4,
  /// @brief cross
  CROSS = 5,
  /// @brief no_stop
  NO_STOP = 6,
  /// @brief crosswalk
  CROSSWALK = 7,
  /// @brief stop line
  STOP_LINE = 8,
  /// @brief speed bump
  SPEED_BUMP = 9,
  /// @brief confluence_left
  CONFLUENCE_LEFT = 10,
  /// @brief confluence_right
  CONFLUENCE_RIGHT = 11,
};

struct alignas(8) MapElement {
  ///@brief id
  char id[KMaxIDLength];
  /// @brief life time
  mutable std::int32_t life_time;
};

struct alignas(8) MapPointsElement : public MapElement {
  ///@brief x, y, z, score
  MapElementPointSet points;
};

struct alignas(8) MapPolygonElement : public MapPointsElement {
  ///@brief center
  Point3f center;
  ///@brief length
  float length;
  /// @brief width
  float width;
  /// @brief height
  float height;
  ///@brief yaw
  float yaw;
};

struct alignas(8) RoadEdge : public MapPointsElement {
  ///@brief type
  RoadEdgeCategory category;
};

struct alignas(8) LaneDivider : public MapPointsElement {
  ///@brief type
  LaneDividerLineType line_type;
  ///@brief color
  LaneDividerColor color;
};

struct alignas(8) CenterLine : public MapPointsElement {
  ///@brief topo point ids
  fixed_array<char[KMaxIDLength], KCenterlineTopoIDNum> topo_point_ids;
};

struct alignas(8) RoadMarking : public MapPolygonElement {
  /// @brief category
  fixed_array<RoadMarkingCategory, KMaxRoadMarkingCategoryNum> category;
};

/// @brief lane divider joint
struct alignas(8) LaneDividerJoint {
  /// @brief lane divider id 1
  char lane_divider_id1[KMaxIDLength];
  /// @brief lane divider id 2
  char lane_divider_id2[KMaxIDLength];
  /// @brief point
  MapElementPoint point;
};

struct alignas(8) Map {
  /// @brief timestamp
  uint64_t timestamp;
  ///@brief Lane divider;
  MapElementSet<LaneDivider> lane_divider;
  ///@brief lane divider joint;
  MapElementSet<LaneDividerJoint> lane_divider_joint;
  ///@brief road edge
  MapElementSet<RoadEdge> road_edge;
  ///@brief road marking;
  MapElementSet<RoadMarking> road_marking;
  ///@brief center line;
  MapElementSet<CenterLine> center_line;
};
}  // namespace perception
}  // namespace autodrive

#endif  // MAP_INFO_H_
